﻿/******************************************************************************
Module:  SignalAlert.cs
Notices: Copyright (c) 2006-2007 by Jeffrey Richter and Wintellect
******************************************************************************/


using System;
using System.Threading;
using System.Diagnostics;


///////////////////////////////////////////////////////////////////////////////


namespace Microsoft.OfficeCommunicationsServer.Applications.Threading.Threading.AsyncProgModel {
   [DebuggerStepThrough]
   public sealed class SignalAlert<TResult> {
      private AsyncResult<TResult> m_asyncResult;
      private TResult m_result = default(TResult);
      private Int32 m_alertCalled = 0; // false

      public SignalAlert() { }

      public IAsyncResult BeginAlert(AsyncCallback ac, Object state) {
         Interlocked.Exchange(ref m_asyncResult, new AsyncResult<TResult>(ac, state));
         if (Thread.VolatileRead(ref m_alertCalled) != 0)
            m_asyncResult.SetAsCompleted(m_result, true);
         return m_asyncResult;
      }

      public TResult EndAlert(IAsyncResult result) {
         return ((AsyncResult<TResult>) result).EndInvoke();
      }

      public void Alert(TResult result) {
         m_result = result;
         Thread.VolatileWrite(ref m_alertCalled, 1);
         Thread.MemoryBarrier();
         if (m_asyncResult != null)
            m_asyncResult.SetAsCompleted(result, true);
      }
   }
}


//////////////////////////////// End of File //////////////////////////////////